#ifndef __ONLINE__
#define __ONLINE__
#include "util.hpp"
#include <mutex>
#include <unordered_map>
//在线用户管理模块：
//包含的成员：
    //1. 互斥锁保证多线程正确访问
    //2. 游戏大厅中用户id和通信连接的映射
    //3. 游戏房间中用户id和通信连接的映射
//包含的成员函数：
    //1. 添加进入游戏大厅的用户id和通信连接
    //2. 添加进入游戏房间的用户id和通信连接
    //3. 从游戏大厅删除用户id以及对应的通信连接
    //4. 从游戏房间删除用户id以及对应的通信连接
    //5. 通过用户id判断当前用户是否在游戏大厅
    //6. 通过用户id判断当前用户是否在游戏房间
    //7. 通过用户id在游戏大厅中获取对应的通信连接
    //8. 通过用户id在游戏房间中获取对应的通信连接
class online_manager
{
private:
    //保证线程安全
    std::mutex _mutex;
    // 用于建立游戏大厅用户的用户ID与通信连接的关系
    std::unordered_map<uint64_t, wsserver_t::connection_ptr> _hall_user;
    // 用于建立游戏房间用户的用户ID与通信连接的关系
    std::unordered_map<uint64_t, wsserver_t::connection_ptr> _room_user;
    
public:
    // websocket连接建立的时候才会加入游戏大厅&游戏房间在线用户管理
    //添加进入游戏大厅的用户和通信连接
    void enter_game_hall(uint64_t uid, wsserver_t::connection_ptr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_user.insert(std::make_pair(uid, conn));
    }
    //添加进入游戏房间的用户
    void enter_game_room(uint64_t uid, wsserver_t::connection_ptr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_user.insert(std::make_pair(uid, conn));
    }
    // websocket连接断开的时候，移除游戏大厅&游戏房间在线用户管理
    void exit_game_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_user.erase(uid);
    }
    void exit_game_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_user.erase(uid);
    }
    // 通过用户id，判断当前用户是否在游戏大厅
    bool is_in_game_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _hall_user.find(uid);
        if (it == _hall_user.end())
        {
            return false;
        }
        return true;
    }
    // 通过用户id，判断当前用户是否在游戏房间
    bool is_in_game_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _room_user.find(uid);
        if (it == _room_user.end())
        {
            return false;
        }
        return true;
    }
    // 通过用户id在游戏大厅用户管理中获取对应的通信连接
    wsserver_t::connection_ptr get_conn_from_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _hall_user.find(uid);
        if (it == _hall_user.end())
        {
            return wsserver_t::connection_ptr();
        }
        return it->second;
    }
    // 通过用户id在游戏房间用户管理中获取对应的通信连接
    wsserver_t::connection_ptr get_conn_from_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _room_user.find(uid);
        if (it == _room_user.end())
        {
            return wsserver_t::connection_ptr();
        }
        return it->second;
    }
};
#endif